import functools


# 采用functools.wraps的目的是为了使装饰器返回的类型始终是func的类型，否则将返回嵌套高阶函数的中的类型，例如返回的是wraper
# 采用参数*args ,**kw是解决函数多参数的问题
def log(func):
    @functools.wraps(func)
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)

    return wrapper


# 修饰器参数的情况
def logger(pram):
    def log(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print('call %s(): and parsms is %s' % (func.__name__, pram))
            return func(*args, **kw)

        return wrapper

    return log


@log
def showMesage(name, age):
    print("my name is {0} and my age is {1}".format(name, age));


@logger("hello")
def getMessage(name, age):
    print("my name is {0} and my age is {1}".format(name, age));


# 添加多个修饰器来拓展所需的功能
@log
@logger("hello15466")
def recieveMessage(name, age):
    print("my name is {0} and my age is {1}".format(name, age));


if __name__ == '__main__':
    showMesage("ddd", 21);
    getMessage("aaa", 43);
    recieveMessage("ccc", 34);
